﻿// 版权所有 谈少民 2011  此代码由谈少民编写，享有完全的版权。tansm@msn.com 
// 2010-10-25 创建
// 2011-1-29  修改

using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace System.Erp.Runtime.Composition
{
    /// <summary>
    /// 提供一种接口，用于描述零件的组合，可以成为功能包。
    /// </summary>
    /// <remarks>
    /// <para>我们可以认为一个组装件是一组零件的组合，他可能内部提供了很多的零件，其中的一个类也可以提供多个零件。</para>
    /// <para>对应的，你可以认为一个项目配置文件也是一个零件的组合。任何一个零件的组合都能够用一个指针描述。</para>
    /// </remarks>
    public interface IPartCatalog
    {
        /// <summary>
        /// 返回此组合下的所有子组合
        /// </summary>
        /// <returns>返回所有可用的零件组合对象的只读集合，每个组合对应一个动作，用于描述是应用还是取消</returns>
        ReadOnlyCollection<Tuple<PartAction,IPartCatalog>> Catalogs { get; }

        /// <summary>
        /// 返回包中的直接零件集合
        /// </summary>
        /// <returns>所有可用的零件集合的查询器.</returns>
        ReadOnlyCollection<Tuple<PartAction, IPart>> Parts { get; }

        /// <summary>
        /// 返回此组合最终的结果集。
        /// </summary>
        /// <returns>也用的结果集的查询对象。</returns>
        IEnumerable<IPart> GetResult();
    }

    /// <summary>
    /// 零件在组装时的动作，包括应用和取消
    /// </summary>
    public enum PartAction
    {
        /// <summary>
        /// 应用
        /// </summary>
        Apply,
        /// <summary>
        /// 取消
        /// </summary>
        Disable
    }

    //TODO:
    //1、引入一个 源，可以展开看见子源
    //2、类上的众多Attribute如何分解呢？
    //3、某个源或零件如何使用 System.Reflection.CustomAttributeData 表示；
    //4、要通过 System.Reflection.CustomAttributeData 再恢复出 零件对象。
    //5、多个ServiceAttribute其实对应到一个功能点。

    //已知一个源（例如组装件），要获取其标题、唯一识别键等信息；
    //从一个源中搜索新的源对象；
}
